using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using GameMain.Scripts.Performance;
using UnityEngine;
using Debug = UnityEngine.Debug;
using Random = UnityEngine.Random;

namespace HotFix.Performance
{
    public class Performance
    {
        private static void Test0(GameObject obj)
        {
            //Empty
            for (var i = 0; i < 10000; ++i)
            {
            }
        }

        private static void Test1(GameObject obj)
        {
            var cnt = 0;
            for (var i = 0; i < 10000; ++i)
            {
                cnt++;
            }
        }

        private static void Test2(GameObject obj)
        {
            for (var i = 0; i < 1000; ++i)
            {
                var tmp = new Vector3(0, 0, 0);
            }
        }

        private static void Test3(GameObject obj)
        {
            for (var i = 0; i < 100; ++i)
            {
                obj.transform.position = obj.transform.position;
            }
        }

        private static void Test4(GameObject obj)
        {
            for (var i = 0; i < 100; ++i)
            {
                obj.transform.rotation = obj.transform.rotation;
            }
        }

        private static void Test5(GameObject obj)
        {
            var tmp = new GameObject();
            UnityEngine.Object.Destroy(tmp);
        }

        private static void Test6(GameObject obj)
        {
            for (var i = 0; i < 100; ++i)
            {
                var t1 = Quaternion.Euler(0, 0, 0);
                var t2 = Quaternion.Euler(1, 1, 1);
                Quaternion.Slerp(t1, t2, Random.Range(0f, 1f));
            }
        }

        private static readonly Dictionary<string, Action<GameObject>> STestAction =
            new Dictionary<string, Action<GameObject>>
            {
                ["test0"] = Test0,
                ["test1"] = Test1,
                ["test2"] = Test2,
                ["test3"] = Test3,
                ["test4"] = Test4,
                ["test5"] = Test5,
                ["test6"] = Test6,
            };

        private static float CallFunc(string name, GameObject obj, uint cnt)
        {
            if (!STestAction.TryGetValue(name, out var act) || act == null)
            {
                return -1;
            }

            var sw = Stopwatch.StartNew();
            for (var i = 0; i < cnt; ++i)
            {
                act(obj);
            }

            sw.Stop();
            return (float) ((double) sw.ElapsedTicks / 10000);
        }

        public static void Call(GameObject obj, string tag = "[PerformanceHotFix]\t\t\t")
        {
            var sb = new StringBuilder();
            foreach (var kv in STestAction)
            {
                sb.Append($"{kv.Key}:{CallFunc(kv.Key, obj, PerformanceSetting.Count):F2}ms\t");
            }

            Debug.Log($"[Performance::Call]{tag} cnt:{PerformanceSetting.Count} {sb}");
        }
    }
}
